<template>
  <el-dialog
    class="add-menu-comp"
    :title="title"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    :visible="visible"
    :width="$setRem(800)"
    :before-close="handleCancel">
    <el-form
      element-loading-custom-class="custom-load"
      :model="ruleForm"
      :rules="rules"
      size="medium"
      ref="ruleForm"
      :label-width="$setRem(130)"
      class="rule-form"
    >
      <el-row>
        <el-col :span="12">
          <el-form-item label="分类名称" prop="classId" required>
            <el-select
              v-model="ruleForm.classId"
              filterable
              :disabled="type === 'edit' || option.evtType === 'add'"
              placeholder="请选择菜单分类">
              <el-option
                v-for="item in menuTypes"
                :key="item.id"
                :label="item.className"
                :value="item.id">
                {{ item.className }}
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="name" required>
            <el-input
              type="text"
              placeholder="请输入菜单名称"
              v-model="ruleForm.name">
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="12">
          <el-form-item v-if="ruleForm.type !== '0'" class="tree-form" label="父级名称" prop="parentId">
            <el-input
              placeholder="输入菜单标题进行过滤"
              v-model="ruleForm.parentName"
              @focus="handleFocus"
              @input="handleInput"
              @blur="handleBlur">
            </el-input>
            <el-tree
              v-show="hasShow"
              class="menu-filter-tree"
              ref="tree"
              highlight-current
              :current-node-key="ruleForm.parentId"
              :data="menus"
              :props="defaultProps"
              node-key="id"
              default-expand-all
              @node-click="handleClick"
              :filter-node-method="filterNode">
            </el-tree>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item v-if="ruleForm.type !== '2'" label="菜单图标" prop="icon">
            <el-select
              popper-class="icon-select"
              :popper-append-to-body="false"
              v-model="ruleForm.icon"
              filterable
              placeholder="请选择菜单图标">
              <el-option
                v-for="item in iconList"
                :key="item.icon_id"
                :label="item.name"
                :value="item.icon_id">
                <i :class="`iconfont ${item.font_class}`">{{ item.iconStr }}</i>
                <span class="icon-name">{{ item.name }}</span>
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="12">
          <el-form-item label="菜单类型" prop="type" required>
            <el-radio-group v-model="ruleForm.type" size="medium" @change="handleChange">
              <el-radio-button label="0">目录</el-radio-button>
              <el-radio-button label="1">菜单</el-radio-button>
              <el-radio-button label="2">按钮</el-radio-button>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="菜单排序" prop="sort">
            <el-input-number
              size="small"
              :controls="false"
              placeholder="菜单排序"
              v-model="ruleForm.sort">
            </el-input-number>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="24">
          <el-form-item label="地址" prop="path" :required="ruleForm.type === '1'">
            <el-input
              type="text"
              placeholder="请输入地址"
              v-model.trim="ruleForm.path">
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="12">
          <el-form-item label="权限编码" prop="permission" required>
            <el-select
              v-model="ruleForm.permission"
              filterable
              placeholder="请选择权限编码">
              <el-option
                v-for="item in currentCodeList"
                :key="item.id"
                :label="item.name"
                :value="item.id">
                <span :title="item.name">{{ item.name }}</span>
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="12">
          <el-form-item label="是否外链" prop="target">
            <el-radio-group v-model="ruleForm.target" size="medium">
              <el-radio-button label="1" name="target">是</el-radio-button>
              <el-radio-button label="0" name="target">否</el-radio-button>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="24">
          <el-form-item label="备注" prop="remark">
            <el-input
              type="textarea"
              placeholder="请输入"
              :rows="3"
              v-model="ruleForm.remark">
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button size="medium" @click="handleCancel">取 消</el-button>
      <el-button
        size="medium"
        type="primary"
        :loading="loading"
        @click="hanldeSave">
        保 存
      </el-button>
    </span>
  </el-dialog>
</template>

<script>
import { authCodeList } from '../../mixins/mixins';

export default {
  props: {
    // 弹框是否展示
    visible: {
      type: Boolean,
      default: true
    },
    option: {
      type: Object,
      default: () => ({})
    },
    menus: {
      type: Array,
      default: () => ([])
    },
    // 新增、编辑
    type: {
      type: String,
      default: 'add'
    },
    classId: {
      type: String,
      default: ''
    },
    loading: {
      type: Boolean,
      default: false
    },
    iconList: {
      type: Array,
      default: () => ([])
    },
    menuTypes: {
      type: Array,
      default: () => ([])
    }
  },
  data() {
    return {
      authCodeList,
      pageCodeList: [
        {
          id: '0', name: '公司模块'
        },
        {
          id: '1', name: '项目菜单'
        },
        {
          id: '2', name: '其它'
        },
        {
          id: '3', name: '项目模块'
        },
      ],
      // form表单数据
      ruleForm: {
        id: '',
        classId: '',
        parentId: '',
        name: '',
        type: '1',
        icon: '',
        parentName: '',
        permission: '',
        sort: '',
        path: '',
        target: '0',
        remark: ''
      },
      // form 表单校验规则
      rules: {
        classId: [
          { required: true, message: '请选择菜单分类' },
        ],
        // parentId: [
        //   { required: true, message: '请选择父级菜单' },
        // ],
        permission: [
          { required: true, message: '请选择权限编码', },
        ],
        name: [
          { required: true, message: '请输入菜单名称', },
        ],
        path: [
          {
            validator: this.validatePath,
            trigger: 'blur',
            message: '请输入地址'
          }
        ]
      },
      activeData: {},
      hasShow: false,
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    };
  },
  computed: {
    currentCodeList() {
      return this.ruleForm.type === '2' ? this.authCodeList : this.pageCodeList;
    },
    // 设置弹框标题
    title() {
      return `${this.type === 'add' ? '新增' : '编辑'}菜单`;
    },
  },
  watch: {
    // 监听弹框显示/隐藏
    visible(value) {
      if (!value) {
        Object.keys(this.ruleForm).forEach(key => {
          if (key === 'type') {
            this.ruleForm[key] = '1';
            return;
          }
          if (key === 'target') {
            this.ruleForm[key] = '0';
            return;
          }
          this.ruleForm[key] = '';
        });
      }
    },
    // 回填数据
    option: {
      deep: true,
      handler: function (data) {
        const { parentId, evtType, id } = data;
        const formKeys = Object.keys(this.ruleForm);
        this.ruleForm.classId = this.classId;
        if (evtType === 'add' && id && id !== '0') {
          this.$nextTick(() => {
            const { data } = this.$refs.tree.getNode(id) || {};
            if (data) {
              this.ruleForm.parentName = data.name;
              this.ruleForm.parentId = id;
              this.$refs.tree.setCurrentKey(id , true);
              this.activeData = data || {};
            }
          });
          return;
        }
        data && Object.keys(data).length && formKeys.forEach(key => {
          const value = data[key] || '';
          if (key === 'type') {
            this.ruleForm[key] = value || '1';
            return;
          }
          if (key === 'target') {
            this.ruleForm[key] = value || '0';
            return;
          }
          if (key === 'parentName' && parentId && parentId !== '0') {
            this.$nextTick(() => {
              const { data } = this.$refs.tree.getNode(parentId) || {};
              if (data) {
                this.ruleForm[key] = data.name;
                this.activeData = data || {};
                this.$refs.tree.setCurrentKey(parentId , true);
              }
            });
            return;
          }
          this.ruleForm[key] = value;
        });
      }
    },
  },
  methods: {
    // 校验地址
    validatePath(rule, value, callback) {
      if (this.ruleForm.type === '1') {
        if (!value) {
          callback('请输入地址');
          return;
        }
        callback();
        return;
      }
      callback();
    },
    // 修改菜单类型校验地址
    handleChange(val) {
      this.ruleForm.permission = '';
      val === '0' && this.$refs.ruleForm.validateField('path');
    },
    // 点击菜单节点
    handleClick(data, node, ref) {
      const { id, name } = data;
      this.ruleForm.parentId = id;
      this.activeData = data;
      this.ruleForm.parentName = name;
      this.hasShow = false;
    },
    handleInput(val) {
      this.$refs.tree && this.$refs.tree.filter(val);
    },
    handleFocus() {
      this.hasShow = true;
    },
    handleBlur(e) {
      const className = e.relatedTarget && e.relatedTarget.className;
      this.hasShow = className && /el-tree/g.test(className);
      if (this.ruleForm.parentName !== this.activeData.name) {
        this.ruleForm.parentName = this.activeData.name || '';
      }
    },
    // 过滤节点
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    // 保存
    hanldeSave() {
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          const params = {
            ...this.ruleForm
          };
          if (!params.parentId) delete params.parentId;
          this.$emit('submit', params);
        }
      });
    },
    handleCancel() {
      this.$emit('cancel');
    }
  }
};
</script>

<style scoped lang="scss">
  .add-menu-comp {
    .el-form {
      padding-right: 30px;
    }
    .tree-form {
      /deep/ .el-form-item__content {
        position: relative;
        .menu-filter-tree {
          position: absolute;
          top: 38px;
          left: 1px;
          width: 100%;
          max-height: 300px;
          z-index: 2;
          background-color: #fff;
          border: 1px solid #f1f1f1;
          border-top-color: transparent;
          box-shadow: 0 2px 8px 0 #bbb;
          border-radius: 4px;
          overflow: auto;
        }
      }
    }
  }
  .icon-select {
    .iconfont {
      font-size: 14px;
      margin-right: 10px;
      display: inline-block;
    }
  }
</style>
